package com.xht.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xht.constants.SystemConstants;
import com.xht.domain.entity.Article;
import com.xht.filter.SensitiveFilter;
import com.xht.service.ArticleService;
import com.xht.service.ArticleTagService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
public class AutoUpdateArticle {
    @Autowired
    private ArticleService articleService;
    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private SensitiveFilter sensitiveFilter; //实例化 过滤敏感词 类

    // 辅助方法：从单个<ul>中提取所有链接（处理绝对路径）
    private static List<String> extractLinksFromUl(Element ulElement) {
        List<String> links = new ArrayList<>();
        Elements aTags = ulElement.select("a[href]");
        for (Element a : aTags) {
            String absUrl = a.attr("abs:href"); // 关键！将相对路径转为绝对路径
            links.add(absUrl);
        }
        return links;
    }

    //@Scheduled(cron = "0/20 * * * * ? ")//每20s执行一次该方法
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
    @Transactional
    public void getArticleContent() {
        String url = SystemConstants.WEB_SPIDER_URL; // 要爬取的交通轨道信息URL
        List<List<String>> allLinks = getUrl(url);//要爬取的文章 链接 列表
        System.out.println("---我要开始爬取了---");

        List<String> chengGuiLinks = allLinks.get(0);
        List<String> railwayLinks = allLinks.get(1);
        List<String> internationalLinks = allLinks.get(2);
        List<String> policyLinks = allLinks.get(3);

        //城轨 链接的文章添加到 数据库
        BianliLink(chengGuiLinks, SystemConstants.chengguiId);
        //铁路 链接的文章添加到 数据库
        BianliLink(railwayLinks, SystemConstants.railwayId);
        //国际 链接的文章添加到 数据库
        BianliLink(internationalLinks, SystemConstants.internationalId);
        //政策 链接
        BianliLink(policyLinks, SystemConstants.policyId);

    }

    //遍历 xx链接
    public void BianliLink(List<String> link, Long categoryid) {
        link.forEach(href -> {
            Article article = AutoGetarticle(href, categoryid);
            if (article != null) {
                articleService.getBaseMapper().insert(article);
                //TODO 并且将文章 tag 设置为 "爬虫"(表示给文章是爬取获得的)
                Long articleId = article.getId();
            }
        });
    }

    //提取文章内容并返回
    public Article AutoGetarticle(String href, Long categoryId) {
        //获取文章标题
        try {
            Document document = Jsoup.connect(href).get();
            // 1. 提取标题
            String title = document.selectFirst("div.title").text().trim();
            //如果该文章在 文章表中还没出现,才写进去
            LambdaQueryWrapper<Article> queryWrapper = Wrappers.lambdaQuery(Article.class).eq(StringUtils.hasText(title), Article::getTitle, title);
            Integer count = articleService.getBaseMapper().selectCount(queryWrapper);
            if (count == 0) { //说明还没有存在  则需要添加到文章表中
                //System.out.println(title);
                //2.提取内容
                // 提取正文容器
                Element detailCont = document.selectFirst("div.detailcont");
                Elements paragraphs = detailCont.select("p");
                // 过滤重复标题段落
                List<Element> filteredParagraphs = new ArrayList<>();
                for (Element p : paragraphs) {
                    String pText = p.text().trim();
                    // 核心判断逻辑：排除完全重复标题的段落
                    if (!pText.equals(title)) {
                        filteredParagraphs.add(p);
                    }
                }
                // 构建清洗后的内容
                StringBuilder cleanContent = new StringBuilder();
                for (Element p : filteredParagraphs) {
                    cleanContent.append(p.text().trim()).append("\n\n");
                }
                String content = cleanContent.toString().trim();

                //TODO 增加 文章内容 关键字 判断
                if (sensitiveFilter.containsSensitive(content)) {
                    return null;//直接返回一个空对象即可
                }

                //System.out.println("清洗后内容:\n" + content);
                //3.提取摘要
                String summary = document.select("div.Summary").text();
                //4.创建实体类Article
                Article article = new Article();
                article.setTitle(title);
                article.setSummary(summary);
                article.setContent(content);
                article.setCategoryId(categoryId);
                //article.setStatus("1");//设置文章状态为未审核(草稿)
                return article;
            } else {
                return null;//返回一个空对象
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //更据所给网站,返回 三种不同种类的文章链接
    //提取 文章链接
    public List<List<String>> getUrl(String url) {
        try {
            System.out.println("正在爬取文章");
            Document document = Jsoup.connect(url)
                    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                    .timeout(10000)
                    .get();

            //先定位"城轨","国际","铁路"所有包含所有栏目的父元素
            Element bdCont = document.selectFirst("div.bd.cont");
            //同时定位"政策"包含所有的父元素
            Element element = document.select("div.bd.cont").get(2);
            if (bdCont == null) {
                System.out.println("未找到内容区域");
                return null;
            }
            Elements policyUls = element.select("ul");
            //System.out.println(bdCont.toString());
            Elements allUl = bdCont.select("ul"); // 获取所有<ul>

            // 4. 分别存储四个栏目的链接（根据需求只取前三个）
            List<String> chengGuiLinks = extractLinksFromUl(allUl.get(0));  // 城轨
            List<String> railwayLinks = extractLinksFromUl(allUl.get(1));    // 铁路
            List<String> internationalLinks = extractLinksFromUl(allUl.get(2)); // 国际
            List<String> policyLinks = extractLinksFromUl(policyUls.get(0));//政策


            List<List<String>> AllLinks = new ArrayList<>();
            AllLinks.add(chengGuiLinks);
            AllLinks.add(railwayLinks);
            AllLinks.add(internationalLinks);
            // 政策 链接
            AllLinks.add(policyLinks);
            return AllLinks;

//            // 5. 打印结果验证
//            System.out.println("===== 城轨新闻（" + chengGuiLinks.size() + "条） =====");
//            chengGuiLinks.forEach(System.out::println);
//
//            System.out.println("\n===== 铁路新闻（" + railwayLinks.size() + "条） =====");
//            railwayLinks.forEach(System.out::println);
//
//            System.out.println("\n===== 国际新闻（" + internationalLinks.size() + "条） =====");
//            internationalLinks.forEach(System.out::println);

        } catch (IOException e) {
            System.out.println("爬取失败了!!");
            throw new RuntimeException(e);
        }
    }

    //根据所给网站,返回对应的文章 链接
//    public List<String> articleHrefList(String url) {
//        List<String> list = new ArrayList<String>();
//
//        try {
//            //获取到给网站的html整个信息
//            Document document = Jsoup.connect(url).get();
//            //通过<div class= "bd cont">标签名,来获取所有标签下的信息
//            Elements NewsUrlList = document.select("div.bd.cont");
//            //在获取 子标签 <ul>
//            Elements ul = NewsUrlList.select("ul");
//            Element firstUl = ul.first(); //获取其中的第一个
//            //再获取子标签下 <li>
//            Elements li = null;
//            if (firstUl != null) {
//                li = firstUl.select("li");
//            }
//            //再获取子标签下 <a>
//            Elements a = null;
//            if (li != null) {
//                a = li.select("a");
//            }
//            if (a != null) {
//                a.forEach(href -> {
//                    String ArticleHref = href.attr("abs:href");
//                    list.add(ArticleHref);
////                    System.out.println(ArticleHref);
//                });
//            }
//            return list;
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    }

}
